/**
 * 
 */
package com.fnic.pearl.scheduler.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fnic.pearl.scheduler.constant.PearlErrorCode;
import com.fnic.pearl.scheduler.constant.TestTaskStatus;
import com.fnic.pearl.scheduler.dao.SchedulerStore;
import com.fnic.pearl.scheduler.model.TaskError;
import com.fnic.pearl.scheduler.model.TaskStats;
import com.fnic.pearl.scheduler.model.TestTask;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


/**
 * 通用类型的任务发布接口，主要用于提供给管理节点下发任务
 * 
 * @author HuHaiyang
 * @date 2014/04/24
 */
public class GenericTaskIssueServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;
	private static Logger LOG = Logger.getLogger(GenericTaskIssueServlet.class);
    private Gson gson = new GsonBuilder()
    		.excludeFieldsWithoutExposeAnnotation()
            .setDateFormat("yyyy-MM-dd HH:mm:ss")
            .create();
	
	/*×
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		List<TestTask> tasks = null;
		ObjectMapper om = new ObjectMapper();
		try
        {
            tasks = om.readValue(req.getReader(), new TypeReference<List<TestTask>>(){});
        }
        catch (Exception ex)
        {
            LOG.warn("doPost - invalid json: " + ex.getMessage());
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
		
		if (tasks.size() == 0)
        {
            LOG.warn("GenericTaskIssue - no task!");
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
		
		List<TaskError> errors = new ArrayList<TaskError>();
        for (TestTask tt : tasks)
        {
            if (tt == null)
            {
                LOG.warn("invalid task, is null!");
                continue;
            }
            else if (tt.getTaskId() <= 0)
            {
                LOG.warn("invalid task, taskId [" + tt.getTaskId() + "] <= 0");
                errors.add(new TaskError(tt.getTaskId(), PearlErrorCode.SCHD_ERR_SVC_TASK_ID_INVALID));
                continue;
            }
            else if (tt.getTaskType() == null || tt.getTaskType().equals(""))
            {
            	LOG.warn("invalid task, taskId [" + tt.getTaskId() + "] <= 0");
                errors.add(new TaskError(tt.getTaskId(), PearlErrorCode.SCHD_ERR_SVC_TASK_TYPE_INVALID));
                continue;
            }
            else if (tt.getRun() != TestTask.RUN_IMMEDIATE
                    && tt.getRun() != TestTask.RUN_TIMING)
            {
                LOG.warn("invalid task RunType [" + tt.getRun() + "]");
                errors.add(new TaskError(tt.getTaskId(), PearlErrorCode.SCHD_ERR_SVC_RUN_INVALID));
                continue;
            }
            else if (tt.getEndTime() != null)
            {
                final Calendar now = Calendar.getInstance();
                Calendar endCal = Calendar.getInstance();
                endCal.setTime(tt.getEndTime());
                if (now.compareTo(endCal) >= 0)
                {
                    LOG.info("scheduler rule - now >= end");
                    errors.add(new TaskError(tt.getTaskId(), PearlErrorCode.SCHD_ERR_SVC_INVALID_END_TIME));
                    continue;
                }
            }
            
            LOG.info("recv task - " + gson.toJson(tt));
            tt.setStatus(TestTaskStatus.S_NEW_TASK);
            TaskStats.getInstance().incrRecvTaskNum();
            SchedulerStore.getInstance().putInitTestTask(tt);
        }
		
		resp.setStatus(HttpServletResponse.SC_OK);
	}
}
